home *** CD-ROM | disk | FTP | other *** search
/ Hardcore Gamer Resource Kit / Hardcore Gamer Resource Kit - Disc 2.iso / Utils / UNIX / UNZIP520 / AMIGA / MAKESFX.C < prev    next >
C/C++ Source or Header  |  1995-11-15  |  5KB  |  148 lines

  1. /* MakeSFX: join UnZipSFX and a .zip archive into a single self-extracting   */
  2. /* Amiga program.  On most systems simple concatenation does the job but for */
  3. /* the Amiga a special tool is needed.  By Paul Kienitz, no rights reserved. */
  4. /* This program is written portably, so if anyone really wants to they can   */
  5. /* produce Amiga self-extracting programs on a non-Amiga.  We are careful    */
  6. /* not to mix Motorola-format longwords read from files with native long     */
  7. /* integers.  Not necessarily limited to use with only the Zip format --     */
  8. /* just combine any archive with any self-extractor program that is capable  */
  9. /* of reading a HUNK_DEBUG section at the end as an archive.                 */
  10.  
  11. #include <stat.h>
  12. #include <string.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15.  
  16. typedef unsigned long ulong;
  17. typedef unsigned short bool;
  18. #define false 0
  19. #define true  1
  20.  
  21. /* the following are extracted from Commodore include file dos/doshunks.h: */
  22. #define HUNK_NAME       1000
  23. #define HUNK_CODE       1001
  24. #define HUNK_DATA       1002
  25. #define HUNK_BSS        1003
  26. #define HUNK_RELOC32    1004
  27. #define HUNK_SYMBOL     1008
  28. #define HUNK_DEBUG      1009
  29. #define HUNK_END        1010
  30. #define HUNK_HEADER     1011
  31. #define HUNK_OVERLAY    1013
  32. #define HUNK_BREAK      1014
  33.  
  34. /* Convert a big-endian (Motorola) sequence of four bytes to a longword: */
  35. #define CHARS2LONG(b)   (((b)[0]<<24)|((b)[1]<<16)|((b)[2]<<8)|(b)[3])
  36. /* b must be (unsigned char *) in the above.  Now the reverse: */
  37. #define LONG2CHARS(b,l) ((b)[0]=(l)>>24,(b)[1]=(l)>>16,(b)[2]=(l)>>8,(b)[3]=l)
  38.  
  39. #define COPYBUFFER      16384
  40.  
  41.  
  42. bool CopyData(FILE *out, FILE *inn, ulong archivesize,
  43.               char *outname, char *inname)
  44. {
  45.     static unsigned char buf[COPYBUFFER];
  46.     long bufend, written = 0;
  47.  
  48.     if (archivesize) {
  49.         LONG2CHARS(buf, HUNK_DEBUG);
  50.         bufend = (archivesize + 3) / 4;
  51.         LONG2CHARS(buf + 4, (ulong) bufend);
  52.         if (fwrite(buf, 1, 8, out) < 8) {
  53.             printf("Error writing in-between data to %s\n", outname);
  54.             return false;
  55.         }
  56.     }
  57.     do {
  58.         bufend = fread(buf, 1, COPYBUFFER, inn);
  59.         if (ferror(inn)) {
  60.             printf("Error reading data from %s\n", inname);
  61.             return false;
  62.         }
  63.         if (!archivesize && !written) {   /* true only for first block read */
  64.             if (CHARS2LONG(buf) != HUNK_HEADER) {
  65.                 printf("%s is not an Amiga executable.\n", inname);
  66.                 return false;
  67.             }
  68.         }
  69.         if (fwrite(buf, 1, bufend, out) < bufend) {
  70.             printf("Error writing %s to %s\n", archivesize ? "archive data" :
  71.                                                "self-extractor code", outname);
  72.             return false;
  73.         }
  74.         written += bufend;
  75.     } while (!feof(inn));
  76.     if (archivesize) {
  77.         if (written != archivesize) {
  78.             printf("Wrong number of bytes copied from archive %s\n", outname);
  79.             return false;
  80.         }
  81.         LONG2CHARS(buf, 0);
  82.         bufend = 3 - (written + 3) % 4;
  83.         LONG2CHARS(buf + bufend, HUNK_END);
  84.         bufend += 4;
  85.         if (fwrite(buf, 1, bufend, out) < bufend) {
  86.             printf("Error writing end-marker data to %s\n", outname);
  87.             return false;
  88.         }
  89.     }
  90.     return true;
  91. }
  92.  
  93.  
  94. void main(int argc, char **argv)
  95. {
  96.     FILE *out, *arch, *tool;
  97.     char *toolname = argv[3];
  98.     struct stat ss;
  99.     int ret;
  100.     ulong archivesize;
  101.  
  102.     if (argc < 3 || argc > 4) {
  103.         printf("Usage: %s <result-file> <zip-archive> [<self-extractor-"
  104.                "program>]\nThe third arg defaults to \"UnZipSFX\" in the"
  105.                " current dir.\n", argv[0]);
  106.         exit(20);
  107.     }
  108.     if (!(arch = fopen(argv[2], "rb"))) {
  109.         printf("Could not find archive file %s\n", argv[2]);
  110.         exit(10);
  111.     }
  112.     if (stat(argv[2], &ss) || !(archivesize = ss.st_size)) {
  113.         fclose(arch);
  114.         printf("Could not check size of archive %s, or file is empty.\n",
  115.                argv[2]);
  116.         exit(10);
  117.     }
  118.     if (argc < 4)
  119.         toolname = "UnZipSFX";
  120.     if (!(tool = fopen(toolname, "rb"))) {
  121.         fclose(arch);
  122.         printf("Could not find self-extractor program %s\n", toolname);
  123.         exit(10);
  124.     }
  125.     if (!(out = fopen(argv[1], "wb"))) {
  126.         fclose(arch);
  127.         fclose(tool);
  128.         printf("Could not create output file %s\n", argv[1]);
  129.         exit(10);
  130.     }
  131.     ret = CopyData(out, tool, 0, argv[1], toolname)
  132.           && CopyData(out, arch, archivesize, argv[1], argv[2]) ? 0 : 10;
  133.     fclose(out);
  134.     fclose(arch);
  135.     fclose(tool);
  136.     if (ret) {
  137.         printf("Deleting %s\n", argv[1]);
  138.         remove(argv[1]);
  139.     } else
  140.         printf("%s successfully written.\n", argv[1]);
  141.     exit(ret);
  142. }
  143.  
  144.  
  145. #if (defined(AZTEC_C) && defined(MCH_AMIGA))
  146. void _wb_parse(void) { }
  147. #endif
  148.